package inno.main;
import inno.data.MovingAvgSingelton;
import inno.data.StockAndValue;
import inno.data.DataReaderSingelton;
import inno.specificCrossover.DummyCrossover;
import inno.specificFitness.DummyFitness;
import inno.specificMutaion.DummyMutation;
import inno.specificSelection.DummySelection;
import inno.treeRepro.Chromosome;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;


public class MainStocks {
	
	private DataReaderSingelton stocksData;
	private int stocksSum;
	/*private String stocksNames[] = {"AA","AEP","AES","AMR","AXP","BA","BAC","CAT","CHRW","CNP",	"CNW",
			"CSCO","CSX","CVX","D","DD","DIS","DUK","ED","EIX","EXC","EXPD","FDX","FE","GE",
			"GMT","HD","HPQ","IBM","INTC","JBHT","JNJ","JPM","KO","KSU","LSTR","LUV","MCD",
			"MMM","MRK","MSFT","NEE","NI","NSC","OSG","PCG","PFE","PG","R","SO","T","TRV",
			"UNP","UPS","UTX","VZ","WMB","WMT","XOM"};*/
	private String stocksNames[] ={};
	private World mySandBox;
	
	private HashMap<String,Chromosome> rulesMap;
	
	
	public MainStocks(String type,String datafolder, String filenames,String modelfiles){
		readStockNames(datafolder, filenames);
		if (type.equals("-t")){
			learnInitialize(datafolder, modelfiles);
		}
		else{
			readRules(datafolder,modelfiles);
		}
		
	}
	
	private void learnInitialize(String datafolder, String modelfiles){
		stocksData = DataReaderSingelton.getInstance();
		stocksData.DataReaderFirstinitialize(datafolder);
		//stocksSum = 52;
		stocksData.initialize(stocksNames, stocksSum);
		int bumpsNum = 10;
		// this are the bumps that we are going to use 
		int[] bumps = {5,10,15,25,50,75,100,125,150,175};
		MovingAvgSingelton.getInstance().initialize(stocksSum, stocksNames, bumps, bumpsNum);
		mySandBox = new World(stocksSum, stocksNames, new DummyCrossover(), 
				new DummyFitness(), new DummyMutation(),
				new DummySelection(), 10, 200, 1000);
		mySandBox.Play(datafolder,modelfiles);
	}
	
	private void readRules(String datafolder, String modelfiles){
		rulesMap = new HashMap<String, Chromosome>();
		ArrayList<Chromosome> rules = new ArrayList<Chromosome>();

		// read the new data
		stocksData = DataReaderSingelton.getInstance();
		stocksData.DataReaderFirstinitialize(datafolder);
		//stocksSum = 52;
		stocksData.initialize(stocksNames, stocksSum);
		int bumpsNum = 10;
		// this are the bumps that we are going to use 
		int[] bumps = {5,10,15,25,50,75,100,125,150,175};
		MovingAvgSingelton.getInstance().initialize(stocksSum, stocksNames, bumps, bumpsNum);
		
		try{
			FileInputStream fstream = new FileInputStream(datafolder+'/'+modelfiles+".txt");
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			// help to create the chromos
			Chromosome newChromo, helpChromo = new Chromosome("help");
			while ((strLine = br.readLine()) != null)   {
				// Print the content on the console
				newChromo = helpChromo.createChromosomeFromSchemeString(strLine);
				rules.add(newChromo);
				rulesMap.put(new String(newChromo.getStockFigure()), newChromo);
			}
			//Close the input stream
			in.close();
		}catch (Exception e){
			e.printStackTrace();
		}
		
	}
	
	private double fractionBfrAfter(double bfr, double after){
		return (after/bfr)*100;
	}
	
	private double getPredictedStockRate(String stockName, int bump){
		return rulesMap.get(stockName).getPredictedVal(bump, 0);
		//return mySandBox.getStockChromosome(stockName).getPredictedVal(bump,0);
	}
	
	private double getLastStockRate(String stockName){
		return stocksData.getLastClosingPrice(stockName);
	}

	// returns the stocks we should buy for this period of time
	public void whatToBuy(int bump,String buyfile){		
		
		ArrayList<StockAndValue> stocksFraction = new ArrayList<StockAndValue>();
		
		// calculate the predicted change in rate
		for (int i=0;i<stocksSum;i++){
			StockAndValue stock = new StockAndValue(stocksNames[i],fractionBfrAfter(getLastStockRate(stocksNames[i]),
					getPredictedStockRate(stocksNames[i], bump)));
			stocksFraction.add(stock);
		}
		// sort it
		Collections.sort(stocksFraction, new Comparator<StockAndValue>() {
			@Override
		    public int compare(StockAndValue o1, StockAndValue o2) {
				Double dif = o1.getValue()-o2.getValue();
				if (dif>0.0){
					return 1;
				}
				else if (dif<0.0){
					return -1;
				}
				else{
					return 0;
				}
				// sides replaced because i want the bigget to be in the high indexes
		    }
		});
		/*Collections.sort(stocksFraction,new Comparator<StockAndValue>(){
		       public int compare(StockAndValue a, StockAndValue b){
		           return a.getValue().compareTo(b.getValue());}
		        });*/
		
		int maxIndex = stocksFraction.size()-1;
		
	//	System.out.println(rulesMap.get(stocksFraction.get(maxIndex).getName()));
		double max = stocksFraction.get(maxIndex).getValue();
		
		ArrayList<String> results = new ArrayList<String>();
		// print the top 10 positive change predicted stocks 
		if (max>100){
			results.add(stocksFraction.get(maxIndex).getName());
			//System.out.println(stocksFraction.get(maxIndex).getName());
			// print the top 10 in max difference of 6 percent
			int index = 1;
			while (index<10){
				if (stocksFraction.get(maxIndex-index).getValue()>120){
					results.add(stocksFraction.get(maxIndex-index).getName());
					//System.out.println(stocksFraction.get(maxIndex-index).getName());
					++index;
				}
				else{
					break;
				}
			}
		}
		
		try {
			FileWriter fstream = new FileWriter(buyfile+".txt");
			BufferedWriter out = new BufferedWriter(fstream);
			for (int i=0;i<results.size();i++){
					//System.out.println(stocksChromosomes.get(stocksNames[i]).toString());
				out.write(results.get(i)+'\n');
			}
			 out.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private void readStockNames(String datafolder, String filenames){
		ArrayList<String> stocks = new ArrayList<String>();
		try{
			FileInputStream fstream = new FileInputStream(datafolder+'/'+filenames+".txt");
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			while ((strLine = br.readLine()) != null)   {
				// Print the content on the console
				stocks.add(new String(strLine));
			}
			//Close the input stream
			in.close();
		}catch (Exception e){
			e.printStackTrace();
		}
		stocksNames = stocks.toArray(stocksNames);
		stocksSum = stocks.size();
	}

}
